package com.elric.mall.common.utils;

import com.elric.mall.common.domain.DynamicExcelHeader;
import com.elric.mall.common.domain.ImportBase;
import com.elric.mall.common.exception.ApiException;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ExcelFileUtil {

    /**
     * 导出excel公用方法
     * @param response
     * @param data
     * @param excelName
     */
    public static void toExcel(HttpServletResponse response, List<?> data,String excelName,Object object) {
        OutputStream out = null;
        try {
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(excelName + ".xls", "UTF-8"));
            response.setContentType("application/vnd.ms-excel;charset=UTF-8");
            out = response.getOutputStream();
            HSSFWorkbook hssfWorkbook=ExportExcelUtil.excelWrite(data,"Sheet",true,object);
            hssfWorkbook.write(out);
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if(out!=null){
                    out.close();
                }
            }catch (Exception e1){
                e1.printStackTrace();
            }
        }
    }

    /**
     * 导出excel公用方法-导出xlsx格式
     * @param response
     * @param data
     * @param excelName
     */
    public static <T extends ImportBase> void toExcelWithXlsx(HttpServletResponse response, List<T> data, String excelName, T object) {
        OutputStream out = null;
        try {
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(excelName + ".xlsx", "UTF-8"));
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
            out = response.getOutputStream();
            XSSFWorkbook hssfWorkbook=ExportExcelUtil.excelWriteWithXlsx(data,"Sheet",true, object);
            hssfWorkbook.write(out);
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if(out!=null){
                    out.close();
                }
            }catch (Exception e1){
                e1.printStackTrace();
            }
        }
    }

    /**
     * 动态导出excel公用方法-导出xlsx格式
     * @param response
     * @param data
     * @param dynamicExcelHeaders
     * @param excelName
     */
    public static void toExcelWithXlsx(HttpServletResponse response, List<Object> data, List<DynamicExcelHeader> dynamicExcelHeaders, String excelName) {
        OutputStream out = null;
        try {
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(excelName + ".xlsx", "UTF-8"));
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
            out = response.getOutputStream();
            XSSFWorkbook hssfWorkbook=ExportExcelUtil.excelWriteWithXlsx(dynamicExcelHeaders,data,true);
            hssfWorkbook.write(out);
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if(out!=null){
                    out.close();
                }
            }catch (Exception e1){
                e1.printStackTrace();
            }
        }
    }

    /**
     * 下载文件
     * @param response
     * @param fileName
     * @param inputStream
     */
    public static void downloadFile(HttpServletResponse response, String fileName,InputStream inputStream) {
        OutputStream outputStream = null;
        if(inputStream==null){
            return;
        }
        try {
            // 设置强制下载不打开
            response.setContentType("application/force-download");
            String encodedFileName = URLEncoder.encode(fileName,"UTF-8");
            // 设置文件名
            response.addHeader("Content-Disposition", "attachment;fileName=" + encodedFileName);
            byte[] buffer = new byte[1024];
            outputStream = response.getOutputStream();
            int i = inputStream.read(buffer);
            while (i != -1) {
                outputStream.write(buffer, 0, i);
                i = inputStream.read(buffer);
            }
            outputStream.flush();
        } catch (Exception e) {
            e.printStackTrace();
            throw new ApiException(e.getMessage()) ;
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * @description:文件名在操作系统中不允许出现 / \ ” : | * ? < > 故将其以空替代 <br>
     * @param fileName 文件名
     * @return:
     * @author:fantao.M
     * @date: 2019/5/7 16:02
     */
    public static String replaceIllegalCharacter(String fileName){

        Pattern pattern = Pattern.compile("[\\s\\\\/:\\*\\?\\\"<>\\|]");
        Matcher matcher = pattern.matcher(fileName);

        return matcher.replaceAll("");
    }

    /**
     * @description:验证文件名是否合法 <br>
     * @param fileName 文件名
     * @return:
     * @author:fantao.M
     * @date: 2019/5/7 16:13
     */
    public static boolean isValidFileName(String fileName) {
        if (fileName == null || fileName.length() > 255)
            return false;
        else
            return fileName.matches("[^\\s\\\\/:\\*\\?\\\"<>\\|](\\x20|[^\\s\\\\/:\\*\\?\\\"<>\\|])*[^\\s\\\\/:\\*\\?\\\"<>\\|\\.]$");
    }

    /**
     * 在文件全名中添加文件名后缀
     * @param fileName
     * @param addName
     * @return
     */
    public static String addFileName(String fileName,String addName) {
        int index = fileName.lastIndexOf(".");
        if(index == -1) {
            return fileName+addName;
        }
        return fileName.substring(0,index)+addName+fileName.substring(index);
    }

    /**
     * 更换文件全名的文件类型名称
     * @param fileName
     * @param fileType
     * @return
     */
    public static String changeFileType(String fileName,String fileType) {
        int index = fileName.lastIndexOf(".");
        if(index == -1) {
            return fileName+"."+fileType;
        }
        return fileName.substring(0,index)+"."+fileType;
    }
}
